﻿using System;
using System.Collections.Generic;

using BizElements.Core;

namespace BizElements.BusinessLayer
{
    /// <summary>Maps names of special entity properties such as ownership fields, audit fields etc. These fields affect various aspects of data, business and UI logic.</summary>
    public sealed class FieldMap
    {
        /// <summary>Initializes a new instance of FieldMap class.</summary>
        internal FieldMap()
        {
        }

        /// <summary>Initializes a new instance of FieldMap class.</summary>
        /// <param name="statusPropertyName">Name of optional property that indicates whether the record is active (e.g. 1) or deactivated/deleted (e.g. 0).</param>
        public FieldMap(string statusPropertyName)
        {
            this.StatusPropertyName = statusPropertyName;
        }

        /// <summary>Initializes a new instance of FieldMap class.</summary>
        /// <param name="statusPropertyName">Name of optional property that indicates whether the record is active (e.g. 1) or deactivated/deleted (e.g. 0).</param>
        /// <param name="defaultPropertyName">Name of, typically textual, default property for user interface.</param>
        /// <param name="orderByPropertyName">Optional name of default property by which entities are sorted in collections.</param>
        /// <param name="createdByPropertyName">Name of optional logging property that contains username of actor that created the entity.</param>
        /// <param name="createdOnPropertyName">Name of optional date-time property that contains entity creation timestamp.</param>
        /// <param name="updatedByPropertyName">Name of optional logging property that contains username of actor that was last to update the entity.</param>
        /// <param name="updatedOnPropertyName">Name of optional date-time property that contains last modification timestamp.</param>
        /// <param name="changeTrackingPropertyNames">Optional names of properties used by optimistic offline concurrency control scheme to check if another user or process has changed the object.
        /// Can be same as <see cref="UpdatedOnPropertyName"/> but it may also be a dedicated timestamp/row-version field or even all of the entity fields.
        /// Empty array or <b>null</b> if optimistic offline locking scheme is not used.</param>
        public FieldMap(string statusPropertyName, string defaultPropertyName, string orderByPropertyName, string createdByPropertyName, string createdOnPropertyName, string updatedByPropertyName, string updatedOnPropertyName, string[] changeTrackingPropertyNames)
        {
            this.StatusPropertyName = statusPropertyName;

            this.DefaultPropertyName = defaultPropertyName;
            this.OrderByPropertyName = orderByPropertyName;
            this.CreatedByPropertyName = createdByPropertyName;
            this.CreatedOnPropertyName = createdOnPropertyName;
            this.UpdatedByPropertyName = updatedByPropertyName;
            this.UpdatedOnPropertyName = updatedOnPropertyName;
            this.ChangeTrackingPropertyNames = changeTrackingPropertyNames;
        }

        /// <summary>Initializes a new instance of FieldMap class.</summary>
        /// <param name="statusPropertyName">Name of optional property that indicates whether the record is active (e.g. 1) or deactivated/deleted (e.g. 0).</param>
        /// <param name="defaultPropertyName">Name of, typically textual, default property for user interface.</param>
        /// <param name="orderByPropertyName">Optional name of default property by which entities are sorted in collections.</param>
        /// <param name="createdByPropertyName">Name of optional logging property that contains username of actor that created the entity.</param>
        /// <param name="createdOnPropertyName">Name of optional date-time property that contains entity creation timestamp.</param>
        /// <param name="updatedByPropertyName">Name of optional logging property that contains username of actor that was last to update the entity.</param>
        /// <param name="updatedOnPropertyName">Name of optional date-time property that contains last modification timestamp.</param>
        /// <param name="changeTrackingPropertyNames">Optional names of properties used by optimistic offline concurrency control scheme to check if another user or process has changed the object.
        /// Can be same as <see cref="UpdatedOnPropertyName"/> but it may also be a dedicated timestamp/row-version field or even all of the entity fields.
        /// Empty array or <b>null</b> if optimistic offline locking scheme is not used.</param>
        /// <param name="organizationIdPropertyName">Name of optional property that contains a reference to an organization that owns the entity.</param>
        /// <param name="unitIdPropertyName">Name of optional property that contains a reference to an organisational unit that owns the entity.</param>
        /// <param name="ownerIdPropertyName">Name of optional property that contains a reference to actor/user that owns the entity.</param>
        /// <param name="teamIdPropertyName">Name of optional property that contains a reference to a team of users that work on entity.</param>
        /// <param name="subtypeIdPropertyName">Name of optional property that determines business object subtype, i.e. derived class. The values stored in this field are typically used by factory classes to build instances derived concrete classes.</param>
        public FieldMap(string statusPropertyName, string defaultPropertyName, string orderByPropertyName, string createdByPropertyName, string createdOnPropertyName, string updatedByPropertyName, string updatedOnPropertyName, string[] changeTrackingPropertyNames, string organizationIdPropertyName, string unitIdPropertyName, string ownerIdPropertyName, string teamIdPropertyName, string subtypeIdPropertyName)
        {
            this.StatusPropertyName = statusPropertyName;
            
            this.DefaultPropertyName = defaultPropertyName;
            this.OrderByPropertyName = orderByPropertyName;
            this.CreatedByPropertyName = createdByPropertyName;
            this.CreatedOnPropertyName = createdOnPropertyName;
            this.UpdatedByPropertyName = updatedByPropertyName;
            this.UpdatedOnPropertyName = updatedOnPropertyName;
            this.ChangeTrackingPropertyNames = changeTrackingPropertyNames;

            this.OrganizationIdPropertyName = organizationIdPropertyName;
            this.UnitIdPropertyName = unitIdPropertyName;
            this.OwnerIdPropertyName = ownerIdPropertyName;
            this.TeamIdPropertyName = teamIdPropertyName;
            this.SubtypeIdPropertyName = subtypeIdPropertyName;
        }

        /// <summary>Name of optional property that indicates whether the record is active (e.g. 1) or deactivated/deleted (e.g. 0).</summary>
        public string StatusPropertyName { get; internal set; }

        /// <summary>Name of, typically textual, default property for user interface.</summary>
        public string DefaultPropertyName { get; internal set; }
        /// <summary>Optional name of default property by which entities are sorted in collections.</summary>
        public string OrderByPropertyName { get; internal set; }

        /// <summary>Name of optional logging property that contains username of actor that created the entity.</summary>
        public string CreatedByPropertyName { get; internal set; }
        /// <summary>Name of optional date-time property that contains entity creation timestamp.</summary>
        public string CreatedOnPropertyName { get; internal set; }
        /// <summary>Name of optional logging property that contains username of actor that was last to update the entity.</summary>
        public string UpdatedByPropertyName { get; internal set; }
        /// <summary>Name of optional date-time property that contains last modification timestamp.</summary>
        public string UpdatedOnPropertyName { get; internal set; }

        /// <summary>Name of optional property that contains a reference to an organization that owns the entity.</summary>
        public string OrganizationIdPropertyName { get; internal set; }
        /// <summary>Name of optional property that contains a reference to an organisational unit that owns the entity.</summary>
        public string UnitIdPropertyName { get; internal set; }
        /// <summary>Name of optional property that contains a reference to actor/user that owns the entity.</summary>
        public string OwnerIdPropertyName { get; internal set; }
        /// <summary>Name of optional property that contains a reference to a team of users that work on entity.</summary>
        public string TeamIdPropertyName { get; internal set; }

        /// <summary>Name of optional property that determines business object subtype, i.e. derived class. 
        /// The values stored in this field are typically used by factory classes to build instances derived concrete classes.</summary>
        public string SubtypeIdPropertyName { get; internal set; }

        /// <summary>Names of properties used by optimistic offline concurrency control scheme to check if another user or process has changed the object.
        /// Can be same as <see cref="UpdatedOnPropertyName"/> but it may also be a dedicated timestamp/row-version field or even all of the entity fields.
        /// Empty array or <b>null</b> if optimistic offline locking scheme is not used.</summary>
        public string[] ChangeTrackingPropertyNames { get; internal set; }
    }
}
